home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / bccapp.zip / DBASE.C < prev    next >
C/C++ Source or Header  |  1991-09-15  |  5KB  |  274 lines

  1. /*
  2.  *
  3.  * File management/record access
  4.  *
  5.  * (C) 1990 Vision Softare
  6.  *
  7.  * $Id: dbase.c 1.2002 91/05/06 14:24:00 pcalvin beta $
  8.  *
  9.  * Comments:
  10.  *
  11.  * Much of the work for this is done by others.  ACCESS provides record
  12.  * management and deletion.  INDEX provides use with efficient access
  13.  * to the desired key.  Not much to do but organize and not step
  14.  * on each others toes.
  15.  *
  16.  * Bugs:
  17.  *
  18.  * None documented
  19.  *
  20.  */
  21. #include <ctype.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <conio.h>
  26. #include <io.h>
  27.  
  28. #include <stdhdr.h>
  29.  
  30. #include <dbase.h>
  31.  
  32. /*
  33.  *    If no records are active, clear the field
  34.  *    There is no default index file.
  35.  */
  36. DATABASE::DATABASE(DBASE *pdb,CCH cchRecord,SZ szFileName,BOOL fCreate) : ACCESS(pdb,cchRecord,szFileName,".dtb",fCreate)
  37.     {
  38.     pidCurrent = pidNil;
  39.     cidAvailableMac = cidNil;
  40.     memset(pdb,0,cchRecord);
  41.     }
  42.  
  43. /*
  44.  *    With multiple indexes, we must destroy them ourselves.
  45.  */
  46. DATABASE::~DATABASE()
  47.     {
  48.     for (CID cid = cidNil; cid < cidAvailableMac; cid++)
  49.         delete rgidActive[cid].pinx; 
  50.     }
  51.     
  52. /*
  53.  *    Marks the current record (including indexes)
  54.  */
  55. BOOL DATABASE::FMark()
  56.     {
  57.     PID pid = &rgidActive[0];
  58.     CID cid = cidNil;
  59.  
  60.     while (cid < cidAvailableMac)
  61.         {
  62.          Verify(pid->pinx->FMark());
  63.         
  64.         cid++;
  65.         }
  66.  
  67.     return (ACCESS::FMark());
  68.     }
  69.  
  70. /*
  71.  *    Goes to the previously marked record
  72.  */
  73. BOOL DATABASE::FGotoMark()
  74.     {
  75.     PID pid = &rgidActive[0];
  76.     CID cid = cidNil;
  77.  
  78.     while (cid < cidAvailableMac)
  79.         {
  80.          Verify(pid->pinx->FGotoMark());
  81.         
  82.         cid++;
  83.         }
  84.  
  85.     return (ACCESS::FGotoMark());
  86.     }
  87.     
  88. /*
  89.  *    Create additional indexes..
  90.  */
  91. CID DATABASE::CidIndexOn(SZ szFileName,CHAR *rgchKey,CCH cchKey)
  92.     {
  93.     AssertSz(cidAvailableMac < cidOpenMax,"Too many open index files");
  94.  
  95.     CID cid = cidAvailableMac++;
  96.  
  97.     rgidActive[cid].sz = rgchKey;
  98.     rgidActive[cid].cch = cchKey;
  99.     rgidActive[cid].pinx = new INDEX(szFileName,cchKey);
  100.  
  101.     Verify(FIndexTo(cid));
  102.     
  103.     return (cid);
  104.     }
  105.  
  106. /*
  107.  *    Select the current index
  108.  */
  109. BOOL DATABASE::FIndexTo(CID cid)
  110.     {
  111.     AssertSz(cid < cidAvailableMac,"Index file does not exist");
  112.  
  113.     pidCurrent = &rgidActive[cid];
  114.  
  115.     return (fTrue);
  116.     }
  117.  
  118. /*
  119.  *    Answers with some properties about the index, may specify
  120.  *    a SPECIFIC index now.
  121.  */
  122. SZ DATABASE::SzIndex(CID cid)
  123.     {
  124.     PID pid = (cid == cidError) ? pidCurrent : &rgidActive[cid];
  125.     
  126.     AssertSz(pid != pidNil,"No default index file");
  127.     
  128.     return (pid->sz);
  129.     }
  130.  
  131. CCH DATABASE::CchIndex(CID cid)
  132.     {
  133.     PID pid = (cid == cidError) ? pidCurrent : &rgidActive[cid];
  134.     
  135.     AssertSz(pid != pidNil,"No default index file");
  136.     
  137.     return (pid->cch);
  138.     }
  139.     
  140. /*
  141.  * Deletes the current record, using pidCurrent to
  142.  *    find the next record.
  143.  */
  144. BOOL DATABASE::FDelete()
  145.     {
  146.     REC rec = (pidCurrent != pidNil) ? pidCurrent->pinx->RecDelete() : recError;
  147.     PID pid = &rgidActive[0];
  148.     CID cid = cidNil;
  149.     
  150.     /*
  151.      *    Get rid of this record
  152.      */
  153.     Verify(ACCESS::FDelete()); 
  154.     
  155.     /*
  156.      *    Delete all entries in the other index files
  157.      */
  158.     while (cid < cidAvailableMac)
  159.         {
  160.         if (pid != pidCurrent)
  161.             pid->pinx->RecDelete();
  162.         
  163.         cid++;
  164.         pid++;
  165.         }
  166.  
  167.     /*
  168.      *    Goto the next available record.
  169.      *    Answer if it is available
  170.      */
  171.     return (ACCESS::FGotoRec(rec));
  172.     }
  173.  
  174. /*
  175.  * Saves the current record..
  176.  */
  177. BOOL DATABASE::FSave()
  178.     {
  179.     return (ACCESS::FSave());
  180.     }
  181.  
  182. /*
  183.  * Moves the record pointer to the first record
  184.  */
  185. BOOL DATABASE::FFirst()
  186.     {
  187.     if (pidCurrent == pidNil)
  188.         return (ACCESS::FFirst());
  189.     else
  190.         return (ACCESS::FGotoRec(pidCurrent->pinx->RecFirst()));
  191.     }
  192.  
  193. /*
  194.  *    Moves record pointer to the last record
  195.  */
  196. BOOL DATABASE::FLast()
  197.     {
  198.     if (pidCurrent == pidNil)
  199.         return (ACCESS::FGotoRec(RecMaxQuery() - 1));
  200.     else
  201.         return (ACCESS::FGotoRec(pidCurrent->pinx->RecLast()));
  202.     }
  203.  
  204. /*
  205.  * Moves the record pointer forward 1 record
  206.  */
  207. BOOL DATABASE::FNext()
  208.     {
  209.     if (pidCurrent == pidNil)
  210.         return (ACCESS::FGotoRec(RecQuery() + 1));
  211.     else        
  212.         return (ACCESS::FGotoRec(pidCurrent->pinx->RecNext()));
  213.     }
  214.  
  215. /*
  216.  * Moves the record pointer backwards 1 record
  217.  */
  218. BOOL DATABASE::FPrevious()
  219.     {
  220.     if (pidCurrent == pidNil)
  221.         return (ACCESS::FGotoRec(RecQuery() - 1));
  222.     else
  223.         return (ACCESS::FGotoRec(pidCurrent->pinx->RecPrevious()));
  224.     }
  225.  
  226. /*
  227.  *    Searches for a specific record.
  228.  *    NOTE: By Physical number, nothing to do with the index file
  229.  */
  230. BOOL DATABASE::FGotoRec(REC rec)
  231.     {
  232.     return (ACCESS::FGotoRec(rec));
  233.     }
  234.     
  235. /*
  236.  * Answers if the key can be found.  Does NOT create the record
  237.  */
  238. BOOL DATABASE::FGotoSz(SZ sz,BOOL fMatchIfClose)
  239.     {
  240.     Assert(sz != szNil);
  241.  
  242.     return (ACCESS::FGotoRec(pidCurrent->pinx->RecFromSz(sz,pidCurrent->cch,fMatchIfClose)));
  243.     }
  244.  
  245. /*
  246.  *    Answers if the record may be created.
  247.  *    Updates all the active index files.
  248.  */
  249. BOOL DATABASE::FCreate()
  250.     {
  251.     REC rec = RecCreate();
  252.     PID pid = &rgidActive[0];
  253.     CID cid = cidNil;
  254.  
  255.     while (cid < cidAvailableMac)
  256.         {
  257.          Verify(pid->pinx->RecCreateSz(pid->sz,pid->cch,rec) == rec);
  258.         
  259.         cid++;
  260.         pid++;
  261.         }
  262.  
  263.     return (fTrue);
  264.     }
  265.  
  266. /*
  267.  * Answers with pointer to the DBASE structure for reading..
  268.  */
  269. DBASE *DATABASE::PdbQuery(VOID)
  270.     {
  271.     return ((DBASE *)PinfQuery());
  272.     }
  273.  
  274.